/***************************************************************************
 *   Copyright (C) 2005 by xihe                                            *
 *   xihels@163.com                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "Unit.h"
#include <libgen.h>
#include <sys/stat.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

#include "MainWindow.h"
#include "QQSession.h"
//#include "StatusIcon.h"

namespace {
    struct pipenode {
	QQSession* s;
	InPacket*  p;
    };

    bool file_exists (const char * fileName)
    {
	struct stat buf;
	return (0 == ::stat(fileName, &buf));
    }
}
//StatusIcon* GUnit::statusIcon_ = NULL;
MainWindow* GUnit::mainWindow_ = NULL;
char GUnit::homePath[512];//something like /home/robin/.cyclone
char GUnit::imagePath[512];
char GUnit::soundPath[512];
char GUnit::logPath[512];//something like /home/robin/.cyclone/log
void GUnit::destroy()
{
    delete mainWindow_;
//    delete statusIcon_;
    mainWindow_ = NULL;
//    statusIcon_ = NULL;
}
/*********
 * 这个函数初始化了GUnit的目录变量，
 * 使它们指向$HOME/.cyclone下面的对应目录
 * 同时检测必要的图形文件是否存在
 * 最后创建一个MainWindow的实例
 * ******/
void GUnit::init()
{
    char* homedir = getenv("HOME"); 
    snprintf(homePath, 512, "%s/.cyclone/", homedir);
//    free(homedir);
    mkdir(homePath, S_IRUSR | S_IWUSR | S_IXUSR);
    snprintf(logPath,512,"%s/log/",homePath);
    mkdir(logPath, S_IRUSR | S_IWUSR | S_IXUSR);
    char errorlog[512];
    char lasterror[512];
    snprintf(errorlog, 512, "%s/errorlog", homePath);
    snprintf(lasterror, 512, "%s/errorlog.old", homePath);
    rename(errorlog, lasterror);
    //freopen(errorlog, "w", stderr);

    snprintf(imagePath, 512, "%s/pixmaps/cyclone/image/cyclone.png", PACKAGE_DATA_DIR);
    if (!file_exists(imagePath)) {
	fprintf(stderr, 
		"Error: Can not load image or sounds files : %s\n"
		, PACKAGE_DATA_DIR);
	exit(1);
    }

    snprintf(imagePath, 512, "%s/pixmaps/cyclone/", PACKAGE_DATA_DIR);
    snprintf(soundPath, 512, "%s/sounds/cyclone/", PACKAGE_DATA_DIR);

    if (NULL == mainWindow_)
	mainWindow_ = new MainWindow();
//	statusIcon_= new StatusIcon(mainWindow_);

}


int GInterface::pipe_[2];

void GInterface::init()
{
    if (-1 == pipe(pipe_)) {
	perror("GInterface::GInterface()");
	exit(1);
    }
	///将管道的IO信号与callback函数连接到一起，
	///保证在发生管道读写之后会调用callback函数
    Glib::signal_io().connect(
	    sigc::ptr_fun(GInterface::callback),
	    pipe_[0],
	    Glib::IO_IN | Glib::IO_HUP);
}

void GInterface::destroy()
{
    close(pipe_[0]);
    close(pipe_[2]);
}
    
bool GInterface::sendMessage(void* s1, void* s2)
{
    void* buf[2] = {s1, s2};
    //把接收到Message写入管道给主进程处理
    return (write(pipe_[1], buf, sizeof(buf)) > 0);
}

bool GInterface::callback(Glib::IOCondition condition)
{
	//接收进程于主进程通过管道通讯的回调函数
    pipenode node;
    //读取管道数据
    if (read(pipe_[0], &node, sizeof(pipenode)) > 0 ) {
	//是回复信息，从重发序列里删除响应的输出包，outpackage
	if (node.p->retell())
	    node.s->againSendQueueRemove(node.p->getSequence());
	//process 是InPacket的纯虚函数，会自己调用响应的process函数
	node.p->process(*node.s);
	//printf("I am in Unit.cpp\n after process\n");
    }
    return true;
}


